package com.sky.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sky.constant.MessageConstant;
import com.sky.constant.StatusConstant;
import com.sky.dto.DishDTO;
import com.sky.dto.DishPageQueryDTO;
import com.sky.entity.Category;
import com.sky.entity.Dish;
import com.sky.entity.DishFlavor;
import com.sky.entity.SetmealDish;
import com.sky.exception.DeletionNotAllowedException;
import com.sky.mapper.DishFlavorMapper;
import com.sky.mapper.SetmealDishMapper;
import com.sky.result.PageResult;
import com.sky.result.Result;
import com.sky.service.DishService;
import com.sky.mapper.DishMapper;
import com.sky.utils.BeanCopyUtils;
import com.sky.utils.RedisCache;
import com.sky.vo.DishItemVO;
import com.sky.vo.DishVO;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.DeleteMapping;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
* @author MrWang
* @description 针对表【dish(菜品)】的数据库操作Service实现
* @createDate 2023-10-18 18:07:45
*/
@Service
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish>
    implements DishService{

    @Autowired
    private DishMapper dishMapper;
    @Autowired
    private DishFlavorMapper dishFlavorMapper;
    @Autowired
    private SetmealDishMapper setmealDishMapper;
    @Autowired
    private RedisCache redisCache;

    //菜品列表
    @Override
    public Result dishList(DishPageQueryDTO dishPageQueryDTO) {
        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<Dish>()
                .eq(Objects.nonNull(dishPageQueryDTO.getCategoryId()),Dish::getCategoryId,dishPageQueryDTO.getCategoryId())
                .like(StringUtils.hasText(dishPageQueryDTO.getName()),Dish::getName,dishPageQueryDTO.getName())
                .eq(Objects.nonNull(dishPageQueryDTO.getStatus()),Dish::getStatus,dishPageQueryDTO.getStatus());
        Page<Dish> page = new Page<>(dishPageQueryDTO.getPage(),dishPageQueryDTO.getPageSize());
        dishMapper.selectPage(page, queryWrapper);
        List<Dish> dishList = page.getRecords();

        return Result.success(new PageResult(page.getTotal(),dishList));
    }

    //添加菜品
    @Transactional
    @Override
    public Result saveDish(DishDTO dishDTO) {
        //1.添加菜品
        Dish dish = BeanCopyUtils.copyBean(dishDTO, Dish.class);
        dishMapper.insert(dish);
        //2.先添加菜品关联的口味
        List<DishFlavor> flavors = dishDTO.getFlavors();
        flavors.stream().map(flavor -> {
            flavor.setDishId(dish.getId());
            return dishFlavorMapper.insert(flavor);
                }).collect(Collectors.toList());

        return Result.success();
    }

    //批量删除
    @Transactional
    @Override
    public Result deleteDishes(String ids) {
        String[] idsArray = ids.split(",");
        for (String id : idsArray) {
            //0.判断是否是起售状态 不可删除
            Dish dish = dishMapper.selectById(id);
            if (dish.getStatus() == StatusConstant.ENABLE){
//                return Result.error("该菜品是起售状态，无法删除!!!");
                throw new DeletionNotAllowedException(MessageConstant.DISH_ON_SALE);
            }
            //0.判断是否关联了套餐 不可删除
            LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<SetmealDish>()
                    .eq(SetmealDish::getDishId,id);
            List<SetmealDish> setmealDishes = setmealDishMapper.selectList(queryWrapper);
            if (setmealDishes.size() != 0){
//                return Result.error("该菜品关联了套餐，无法被删除!!!");
                throw new DeletionNotAllowedException(MessageConstant.DISH_BE_RELATED_BY_SETMEAL);
            }

            //1.删除菜品所有口味信息
            LambdaQueryWrapper<DishFlavor> queryWrapper1 = new LambdaQueryWrapper<DishFlavor>()
                    .eq(DishFlavor::getDishId,id);
            dishFlavorMapper.delete(queryWrapper1);
            //2.删除菜品信息
            dishMapper.deleteById(id);

        }
        return Result.success();
    }

    //根据id查询菜品
    @Transactional
    @Override
    public Result getDishById(String id) {
        //1.查询菜品的口味列表
        LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<DishFlavor>()
                .eq(DishFlavor::getDishId,id);
        List<DishFlavor> flavors = dishFlavorMapper.selectList(queryWrapper);
        //2.查询菜品信息
        Dish dish = dishMapper.selectById(id);
        //3.封装
        DishDTO dishDTO = BeanCopyUtils.copyBean(dish, DishDTO.class);
        dishDTO.setFlavors(flavors);

        return Result.success(dishDTO);
    }

    //修改菜品
    @Override
    public Result updateDish(DishDTO dishDTO) {
        //1.先删除之前关联口味记录
        LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<DishFlavor>()
                .eq(DishFlavor::getDishId,dishDTO.getId());
        dishFlavorMapper.delete(queryWrapper);
        //2.添加新的口味记录
        List<DishFlavor> flavors = dishDTO.getFlavors();
        flavors.stream().map(flavor -> {
            flavor.setDishId(dishDTO.getId());
            return dishFlavorMapper.insert(flavor);
        }).collect(Collectors.toList());
        //3.更新菜品
        Dish dish = BeanCopyUtils.copyBean(dishDTO, Dish.class);
        dishMapper.updateById(dish);

        return Result.success();
    }

    //根据分类id查询菜品
    @Override
    public Result getDishesByType(String categoryId) {
        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<Dish>()
                .eq(Dish::getCategoryId,categoryId);
        List<Dish> dishes = dishMapper.selectList(queryWrapper);
        return Result.success(dishes);
    }

    //菜品起售、停售
    @Override
    public Result updateDishStatus(String status, String id) {
        Dish dish = new Dish();
        dish.setId(Long.valueOf(id));
        dish.setStatus(Integer.valueOf(status));
        dishMapper.updateById(dish);
        return Result.success();
    }


    //C端
    //根据分类id查询菜品列表
    //优化 => 使用redis缓存分类下的菜品列表
    @Transactional
    @Override
    public Result getDishListByCategoryId(String categoryId) {
        //0.判断redis是否缓存当前categoryId下的菜品列表或套餐列表
        //TODO 注意:在这里Redis可以使用String存储,也可以使用List存储 但是使用String存储需要将结果强转为(List<DishVO>)
//        List<DishVO> dishVoList = (List<DishVO>)redisCache.getCacheObject("dish_" + categoryId);//String方式
        List<DishVO> dishVoList = redisCache.getCacheList("dish_" + categoryId);//List方式
//        System.out.println("1==================="+dishVoList);
        //1.没有缓存就获取菜品列表并缓存redis
        if (dishVoList == null || dishVoList.size() == 0){
            LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<Dish>()
                    .eq(Dish::getStatus,StatusConstant.ENABLE)
                    .eq(Dish::getCategoryId,categoryId);
            List<Dish> dishes = dishMapper.selectList(queryWrapper);
            List<DishVO> dishVos = BeanCopyUtils.copyBeanList(dishes, DishVO.class);
            //给菜品列表中每个菜品的口味赋值
            dishVoList = dishVos.stream().map(dishVO -> {
                LambdaQueryWrapper<DishFlavor> queryWrapper1 = new LambdaQueryWrapper<DishFlavor>()
                        .eq(DishFlavor::getDishId, dishVO.getId());
                List<DishFlavor> dishFlavors = dishFlavorMapper.selectList(queryWrapper1);
                dishVO.setFlavors(dishFlavors);
                return dishVO;
            }).collect(Collectors.toList());
//            redisCache.setCacheObject("dish_"+categoryId,dishVoList);//String方式缓存
            redisCache.setCacheList("dish_"+categoryId,dishVoList);//List方式缓存
//            System.out.println("2==================="+dishVoList);
        }
        //2.有缓存数据 直接返回给前端
        return Result.success(dishVoList);
    }

}




